package com.next.aap.server.persistance.helper;

import java.util.List;

import org.springframework.stereotype.Component;

import com.next.aap.server.persistance.User;
import com.next.core.db.page.PageInfo;
import com.next.core.db.page.PageResult;
import com.next.core.db.page.QueryParam;
import com.next.core.db.validator.ObjectValidator;
import com.next.core.exception.AppException;
import com.next.ext.core.db.page.HibernateQueryParamPageInfo;
import com.next.ext.core.persistance.dao.BasePersistanceDao;

@Component
public class UserHelper extends BasePersistanceDao<User> implements ObjectValidator<User> {

	/**
	 * Creates/updates a user in Database
	 * 
	 * @param user
	 * @return saved user
	 * @throws AppException
	 */
	public User saveUser(User user) throws AppException
	{
		checkIfUserExistsWithSameEmail(user);
		checkIfUserExistsWithSameMobile(user);
		user.setEmailUp(user.getEmail().toUpperCase());
		user = super.saveObject(user);
		return user;
	}

	/**
	 * deletes a user in Database
	 * 
	 * @param user
	 * @return updated user
	 * @throws AppException
	 */
	public void deleteUser(User user) throws AppException {
		super.deleteObject(user);
	}

	/**
	 * return a User with given primary key/id
	 * 
	 * @param id
	 * @return User with PK as id(parameter)
	 * @throws AppException
	 */
	public User getUserById(Long id) throws AppException
	{
		User user = super.getObjectByPK(User.class, id);
		return user;
	}

	/**
	 * @param pageInfo
	 * @return search result
	 * @throws AppException
	 */
	public PageResult<User> searchUsers(PageInfo pageInfo) throws AppException
	{
		return super.findObject(User.class, pageInfo);
	}

	public List<User> getAllUsers() throws AppException
	{
		PageInfo pageInfo = null;
		return super.findObject(User.class, pageInfo).getResultList();
	}
	public User getUserByEmail(String userEmail) throws AppException{
		System.out.println("getUserByEmail "+userEmail);
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam emailQueryParam = new QueryParam();
		emailQueryParam.setCaseSenstive(false);
		emailQueryParam.setField("emailUp");
		emailQueryParam.setFieldType(QueryParam.FIELD_TYPE_STRING);
		emailQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		emailQueryParam.setValue(userEmail.toUpperCase());
		pageInfo.addCriteria(emailQueryParam);
		
		PageResult<User> pr = this.searchUsers(pageInfo);
		if(pr.getResultList().size() <= 0){
			return null;
		}
		return pr.getResultList().get(0);
	}
	public List<User> getUserAtAndChildLocation(long locationId) throws AppException{
		System.out.println("getUserAtAndChildLevel "+locationId);
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam levelQueryParam = new QueryParam();
		levelQueryParam.setCaseSenstive(false);
		levelQueryParam.setField("locationId");
		levelQueryParam.setFieldType(QueryParam.FIELD_TYPE_STRING);
		levelQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		levelQueryParam.setValue(locationId);
		pageInfo.addCriteria(levelQueryParam);
		
		PageResult<User> pr = this.searchUsers(pageInfo);
		List<User> userList = pr.getResultList();
		System.out.println("userList = "+userList);
		

		HibernateQueryParamPageInfo parentLocationPageInfo = new HibernateQueryParamPageInfo();
		QueryParam parentLocationQueryParam = new QueryParam();
		parentLocationQueryParam.setCaseSenstive(false);
		parentLocationQueryParam.setField("location.parentLocationId");
		parentLocationQueryParam.setFieldType(QueryParam.FIELD_TYPE_STRING);
		parentLocationQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		parentLocationQueryParam.setValue(locationId);
		parentLocationPageInfo.addCriteria(parentLocationQueryParam);
		
		PageResult<User> parentLocationPageResult = this.searchUsers(parentLocationPageInfo);
		System.out.println("parentLocationPageResult.getResultList() = "+parentLocationPageResult.getResultList());
		userList.addAll(parentLocationPageResult.getResultList());
		return userList;
	}
	public User getUserByMobile(String mobile) throws AppException{
		System.out.println("getUserByMobile "+mobile);
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam emailQueryParam = new QueryParam();
		emailQueryParam.setCaseSenstive(false);
		emailQueryParam.setField("mobile");
		emailQueryParam.setFieldType(QueryParam.FIELD_TYPE_STRING);
		emailQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		emailQueryParam.setValue(mobile);
		pageInfo.addCriteria(emailQueryParam);
		
		PageResult<User> pr = this.searchUsers(pageInfo);
		if(pr.getResultList().size() <= 0){
			return null;
		}
		return pr.getResultList().get(0);
	}

	public void validateObjectForCreate(User user) throws AppException {
		System.out.println("validateObjectForCreate");
		checkIfStringMissing("Name", user.getName());
		checkIfStringMissing("Mobile", user.getMobile());
		checkIfStringMissing("Email", user.getEmail());
		//checkIfUserExistsWithSameEmail(user);
		//checkIfUserExistsWithSameMobile(user);
	}

	public void validateObjectForUpdate(User user) throws AppException {
		checkIfStringMissing("Name", user.getName());
		checkIfStringMissing("Mobile", user.getMobile());
		checkIfStringMissing("Email", user.getEmail());
		//checkIfUserExistsWithSameEmail(user);
		//checkIfUserExistsWithSameMobile(user);
	}
	private void checkIfUserExistsWithSameEmail(User user) throws AppException{
		System.out.println("checkIfUserExistsWithSameEmail "+user.getEmail());
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam emailQueryParam = new QueryParam();
		emailQueryParam.setCaseSenstive(false);
		emailQueryParam.setField("emailUp");
		emailQueryParam.setFieldType(QueryParam.FIELD_TYPE_STRING);
		emailQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		emailQueryParam.setValue(user.getEmail().toUpperCase());
		pageInfo.addCriteria(emailQueryParam);
		
		if(user.getId() != null && user.getId() > 0){
			QueryParam userIdQueryParam = new QueryParam();
			userIdQueryParam.setCaseSenstive(false);
			userIdQueryParam.setField("id");
			userIdQueryParam.setFieldType(QueryParam.FIELD_TYPE_NUMBER);
			userIdQueryParam.setOperator(QueryParam.OPERATOR_NOT_EQUAL);
			userIdQueryParam.setValue(user.getId());
			pageInfo.addCriteria(userIdQueryParam);
		}
		
		PageResult<User> pr = this.searchUsers(pageInfo);
		if(pr.getResultList().size() > 0){
			throw new AppException("User already exists with email = "+user.getEmail());
		}
	}
	private void checkIfUserExistsWithSameMobile(User user) throws AppException{
		System.out.println("checkIfUserExistsWithSameMobile "+user.getMobile());
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam emailQueryParam = new QueryParam();
		emailQueryParam.setCaseSenstive(false);
		emailQueryParam.setField("mobile");
		emailQueryParam.setFieldType(QueryParam.FIELD_TYPE_STRING);
		emailQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		emailQueryParam.setValue(user.getMobile());
		pageInfo.addCriteria(emailQueryParam);
		
		if(user.getId() != null && user.getId() > 0){
			QueryParam userIdQueryParam = new QueryParam();
			userIdQueryParam.setCaseSenstive(false);
			userIdQueryParam.setField("id");
			userIdQueryParam.setFieldType(QueryParam.FIELD_TYPE_NUMBER);
			userIdQueryParam.setOperator(QueryParam.OPERATOR_NOT_EQUAL);
			userIdQueryParam.setValue(user.getId());
			pageInfo.addCriteria(userIdQueryParam);
		}
		
		PageResult<User> pr = this.searchUsers(pageInfo);
		if(pr.getResultList().size() > 0){
			throw new AppException("User already exists with mobile = "+user.getMobile());
		}
	}
}